import { observer } from "mobx-react-lite"
import React, { FC, useEffect, useState } from "react"
import { useFocusEffect } from "@react-navigation/native"
import { AppStackScreenProps, navigate } from "app/navigators"
import { useAppDispatch, useAppSelector } from "app/redux/hooks"
import { View, ViewStyle, FlatList, Text, StyleSheet, useWindowDimensions } from "react-native"
import { useSafeAreaInsetsStyle } from "../../utils/useSafeAreaInsetsStyle"
import { RenderEvent } from "./RenderEvent"
import { scale } from "react-native-size-matters"
import { Calendar } from "react-native-big-calendar"
import { addDays, subDays, format } from "date-fns"

//Local Imports
import HomeHeader from "./HomeHeader"
import Appointment from "./Appointment"
import { colors, spacing } from "../../theme"
import ActionMenu from "../../components/ActionMenu"
import MainHeader from "app/components/MainHeader"
import {
  increaseOffset,
  resetAppointment,
  setAppointmentMode,
} from "app/redux/slices/appointmentSlice"
import { getAppointment } from "app/redux/actions/appointmentActions"
import { getSpecificTimeAppointments } from "app/services/apis/getAppointment"
import { eventDateTimeConverter } from "app/services/helperFunctions/timeConverter"
import DatePicker from "react-native-date-picker"
import LoaderComponent from "app/components/Loader"
import { RenderDayEvent } from "./RenderDayEvent"
import { eventCellStyle, eventDayCellStyle } from "./EventStyles"

interface AppointmentsScreenProps extends AppStackScreenProps<"Welcome"> {}

const ItemSeparatorComponent = () => {
  return <View style={{ height: 15 }} />
}

export const Appointments: FC<AppointmentsScreenProps> = observer(function WelcomeScreen() {
  const dispatch = useAppDispatch()
  const appointmentSelector = useAppSelector((state) => state?.appointment)
  const $bottomContainerInsets = useSafeAreaInsetsStyle(["bottom", "top"])

  const [selectedMenu, setSelectedMenu] = useState("list")
  const [events, setEvents] = useState([])
  const [datePicker, setDatePicker] = useState(false)
  const [givenDate, setGivenDate] = useState(new Date())
  const [loading, setLoading] = useState(false)

  const { height } = useWindowDimensions()

  const onEndReached = () => {
    if(appointmentSelector?.offset <= appointmentSelector?.count){
      dispatch(increaseOffset())
    }
  }

  const onPressCalendar = () => {
    setDatePicker(true)
  }

  useFocusEffect(
    React.useCallback(() => {
      if (selectedMenu === "list") {
        dispatch(getAppointment({ offset: appointmentSelector.offset }))
      }
    }, [appointmentSelector?.offset, selectedMenu]),
  )

  useEffect(() => {
    if (selectedMenu !== "week") {
      setEvents([])
    }
  }, [selectedMenu])

  useFocusEffect(
    React.useCallback(() => {
      return () => {
        dispatch(resetAppointment())
      }
    }, []),
  )

  useFocusEffect(
    React.useCallback(() => {
      if (selectedMenu === "week") {
        setLoading(true)
        const [start_date, end_date] = [subDays(givenDate, 5), addDays(givenDate, 5)].map((date) =>
          format(date, "yyyy-MM-dd"),
        )
        getSpecificTimeAppointments({ start_date, end_date })
          .then((result: any) => {
            setLoading(false)
            let data = result?.data.map((element) => {
              return eventDateTimeConverter(element)
            })
            setEvents(data)
          })
          .catch((error: any) => {
            setLoading(false)
            console.log("error in fetching weekly appointments", error)
          })
      } else if (selectedMenu === "day") {
        setLoading(true)
        const [start_date, end_date] = [givenDate, addDays(givenDate, 1)].map((date) =>
          format(date, "yyyy-MM-dd"),
        )
        getSpecificTimeAppointments({ start_date, end_date })
          .then((result: any) => {
            setLoading(false)
            let data = result?.data.map((element) => {
              return eventDateTimeConverter(element)
            })
            setEvents(data)
          })
          .catch((error: any) => {
            setLoading(false)
            console.log("error in fetching weekly appointments", error)
          })
      }
    }, [selectedMenu, givenDate]),
  )

  return (
    <View style={[$container, $bottomContainerInsets]}>
      <MainHeader />
      <HomeHeader
        selectedMenu={selectedMenu}
        setSelectedMenu={(item) => {
          setSelectedMenu(item),
            setGivenDate(new Date()),
            dispatch(setAppointmentMode(item)),
            dispatch(resetAppointment())
        }}
        onPressCalendar={onPressCalendar}
        givenDate={givenDate.toLocaleDateString("en-US", {
          year: "numeric",
          month: "long",
          day: "numeric",
        })}
      />
      {loading || appointmentSelector?.loading ? (
        <View style={styles.overlay}>
          <LoaderComponent />
        </View>
      ) : (
        <>
          {selectedMenu === "list" ? (
            <>
              <FlatList
                data={appointmentSelector?.Appointments}
                renderItem={({ item }) => <Appointment item={item} />}
                ItemSeparatorComponent={ItemSeparatorComponent}
                contentContainerStyle={{ paddingHorizontal: spacing.lg, paddingBottom: 160 }}
                onEndReached={onEndReached}
                ListEmptyComponent={
                  <View style={[styles.emptyComponent, { height: height * 0.7 }]}>
                    <Text style={styles.listText}>No records found</Text>
                  </View>
                }
              />

              <ActionMenu
                onCreateAppointment={() => {
                  //@ts-ignore
                  navigate("AddAppointment")
                }}
              />
            </>
          ) : (
            <View style={{ flex: 1, paddingBottom: scale(100) }}>
              <Calendar
                width={scale(500)}
                height={scale(600)}
                //@ts-ignore
                eventCellStyle={
                  appointmentSelector?.mode === "week" ? eventCellStyle : eventDayCellStyle
                }
                hourRowHeight={scale(100)}
                hourStyle={{ color: "black" }}
                weekDayHeaderHighlightColor="red"
                headerContainerStyle={{
                  height: scale(25),
                }}
                dayHeaderHighlightColor="red"
                events={events}
                renderEvent={appointmentSelector?.mode === "week" ? RenderEvent : RenderDayEvent}
                //@ts-ignore
                mode={selectedMenu}
                showTime={true}
                ampm={true}
                hideNowIndicator={true}
                date={givenDate}
                activeDate={givenDate}
                swipeEnabled={false}
                onPressEvent={(event) => {
                  //@ts-ignore
                  navigate("EditAddAppointment", { id: event?.id })
                }}
                dayHeaderStyle={{ bottom: scale(45) }}
                overlapOffset={appointmentSelector?.mode === "week" ? 19 : 100}
              />
            </View>
          )}
        </>
      )}
      <DatePicker
        locale="en"
        modal
        mode={"date"}
        open={datePicker}
        date={new Date()}
        minuteInterval={15}
        onConfirm={(date) => {
          setLoading(true)
          setDatePicker(false)
          setGivenDate(date)
        }}
        onCancel={() => {
          setDatePicker(false)
        }}
      />
    </View>
  )
})

const $container: ViewStyle = {
  flex: 1,
  backgroundColor: colors.background,
}

const styles = StyleSheet.create({
  headerContainer: { flexDirection: "row", justifyContent: "space-between" },
  arrowBtn: {
    paddingVertical: scale(2),
    width: scale(90),
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "center",
    borderColor: colors?.border,
    borderWidth: StyleSheet.hairlineWidth * 2,
    borderRadius: scale(10),
    marginHorizontal: scale(10),
    backgroundColor: colors.white,
  },
  txt: {
    color: colors.black,
    fontSize: scale(12),
  },
  overlay: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: "rgba(0, 0, 0, 0.5)",
    justifyContent: "center",
    alignItems: "center",
  },
  listText: {
    color: colors.black,
    fontSize: scale(18),
    fontWeight: "600",
  },
  emptyComponent: {
    alignItems: "center",
    justifyContent: "center",
    flex: 1,
  },
})
